package fr.jade.console.cmd;

import java.net.InetAddress;
import java.util.HashMap;
import java.util.LinkedList;

import org.objectweb.fractal.adl.Factory;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.factory.GenericFactory;
import org.objectweb.fractal.api.type.InterfaceType;
import org.objectweb.fractal.api.type.TypeFactory;
import org.objectweb.fractal.util.Fractal;

import fr.jade.console.core.AbstractCommand;
import fr.jade.console.core.Command;
import fr.jade.console.core.Environment;
import fr.jade.fraclite.adl.FactoryFactory;
import fr.jade.fraclite.orb.registry.NamingService;
import fr.jade.fraclite.util.FracLite;
import fr.jade.reflex.api.control.ReflexController;
import fr.jade.reflex.util.Reflex;
import fr.jade.util.FractalUtil;

public class Boot extends AbstractCommand implements Command {

  public static Component dirty = null;
  
  public String getDescription(){
    return "boots a jade configuration";
  }
  
  public String getHelp(){
    return "boot <jade_fractal>";
  }
  /**
   * boot a jade configuration.
   * 
   * @param pargs
   *          args[0] = cmdName
   *          args[1] = jade name 
   */

  public Object execute(String[] args, Environment env) throws Throwable {

    HashMap<String, Object> context = new HashMap<String, Object>();
    
    String jadeName = args[1];

    Component boot = Fractal.getBootstrapComponent();
    GenericFactory gf = (GenericFactory) boot.getFcInterface("generic-factory");
    TypeFactory tf = (TypeFactory) boot.getFcInterface("type-factory");
    Component metaBoot = gf.newFcInstance(tf.createFcType(new InterfaceType[]{}), "node", null);
    Component execBoot = gf.newFcInstance(tf.createFcType(new InterfaceType[]{}), "node", null);
    
    Reflex.setAsDualComponent(metaBoot,execBoot);
    Reflex.getReflexController(metaBoot).setLevel(ReflexController.META_LEVEL);
    Reflex.getReflexController(execBoot).setLevel(ReflexController.EXEC_LEVEL);
    
    dirty = execBoot;
    
    FractalUtil.getNameController(execBoot).setFcName("jadeBoot");
    
    FracLite.getAttributeController(execBoot).setAttribute("hostName", InetAddress.getLocalHost().getHostName());
    context.put("bootstrap", execBoot);
    
    Factory f = FactoryFactory.getFactory(FactoryFactory.FRACLITE_FACTORY, FactoryFactory.FRACLITE_BACKEND, new HashMap<String, Object>());
    Component jade = (Component) (f.newComponent(jadeName, context));
    FractalUtil.getNameController(jade).setFcName("jade");
    Fractal.getLifeCycleController(jade).startFc();

    NamingService ns = (NamingService) (jade.getFcInterface("registry"));
    ns.rebind("jade", jade);

    env.setEnvVar("curent", jade);
    env.setEnvVar("root",jade);
    
    return null;
  }


  public String getName() {
    return "boot";
  }

}
